package protocal;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;

public class MessageUtil {

	// 将消息对象转化成字节数组
	public static byte[] writeMessage(Message m) {

		if (m == null) {
			return null;
		}

		int bodyLen = 0;
		byte[] bodyBytes = null;

		if (m.body != null) {
			bodyBytes = m.body.toData();
			bodyLen = bodyBytes.length;
		}

		ByteBuffer buf = ByteBuffer.allocate(16 + bodyLen);

		buf.putInt(bodyLen);

		buf.putLong(m.seq);
		buf.put((byte) m.cmd);
		buf.put((byte) m.version);
		buf.put((byte) 0);
		buf.put((byte) 0);

		if (bodyBytes != null) {
			buf.put(bodyBytes, 0, bodyLen);
		}

		buf.rewind();
		byte[] bytes = new byte[buf.capacity()];
		buf.get(bytes, 0, bytes.length);
		return bytes;
	}

	// 将消息字节序列转换成消息对象
	public static Message readMessage(InputStream in) {
		try {
			// 读取16字节头
			byte[] headBuf = new byte[16];
			int len = in.read(headBuf);
			if (len <= 0) {
				return null;
			}

			Message m = new Message();

			ByteBuffer headBb = ByteBuffer.wrap(headBuf);
			int bodyLen = headBb.getInt();
			m.seq = headBb.getLong();
			m.cmd = (int) headBb.get();
			m.version = (int) headBb.get();
			headBb.get();
			headBb.get();

			if (bodyLen > 0) {
				byte[] bodyBytes = new byte[bodyLen];

				len = in.read(bodyBytes);

				if (len != bodyLen) {
					return null;
				}

				switch (m.cmd) {
				case Constants.MSG_AUTH_TOKEN:
					AuthenticationToken at = new AuthenticationToken();
					at.fromData(bodyBytes);
					m.body = at;
					break;
				case Constants.MSG_AUTH_STATUS:
					AuthenticationStatus as = new AuthenticationStatus();
					as.fromData(bodyBytes);
					m.body = as;
					break;
				case Constants.MSG_IM:
					IMMessage imm = new IMMessage();
					imm.fromData(bodyBytes);
					m.body = imm;
					break;
				case Constants.MSG_ACK:
					MessageACK ma = new MessageACK();
					ma.fromData(bodyBytes);
					m.body = ma;
					break;
				case Constants.MSG_GROUP_NOTIFICATION:
					GroupNotification gn = new GroupNotification();
					gn.fromData(bodyBytes);
					m.body = gn;
					break;
				case Constants.MSG_GROUP_IM:
					IMMessage imm1 = new IMMessage();
					imm1.fromData(bodyBytes);
					m.body = imm1;
					break;
				case Constants.MSG_PEER_ACK:
					MessagePeerACK mpa = new MessagePeerACK();
					mpa.fromData(bodyBytes);
					m.body = mpa;
					break;
				case Constants.MessageInputing:
					MessageInputing mi = new MessageInputing();
					mi.fromData(bodyBytes);
					m.body = mi;
					break;
				case Constants.MSG_ONLINE_STATE:
					MessageOnlineState mos = new MessageOnlineState();
					mos.fromData(bodyBytes);
					m.body = mos;
					break;
				case Constants.MSG_DEVICE_KICK:
					DeviceKick dk = new DeviceKick();
					dk.fromData(bodyBytes);
					m.body = dk;
					break;
				default:
					break;
				}
			}

			return m;

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	}
}
